import com.alibaba.fastjson.JSONObject;
import com.sun.tools.attach.AgentInitializationException;
import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;

import static java.lang.System.exit;

/**
 * @author ykw
 * 2020/11/12
 */
public class HotUpdateMain {


    public static void main(String[] args) {
        String hotUpdateCfgFilePath = args[0];
        try {
            Properties properties = loadProperties(hotUpdateCfgFilePath);
            // 需要更新的类全限定名集合
            String nameSetJson = properties.get("nameSet").toString();
            // 需要更新的java进程id集合
            String javaIdSetStr = properties.get("javaPIdSet").toString();
            // 代理包路径
            String agentJarPath = properties.get("agentJarPath").toString();
            // 新的class文件目录
            String classFilePath = properties.get("classFilePath").toString();

            JSONObject params = new JSONObject();
            params.put("classFilePath", classFilePath);
            params.put("classNameSet", nameSetJson);

            List<String> javaPidList = JSONObject.parseArray(javaIdSetStr, String.class);
            for (String pId : javaPidList) {
                System.out.println("update pid - > " + pId);
                hostUpdate(pId, params.toJSONString(), agentJarPath);
            }
        } catch (Exception var10) {
            var10.printStackTrace();
        }

    }

    /**
     * 执行单个进程更新
     * @param pid
     * @param params
     * @param agentJarPath
     */
    private static void hostUpdate(String pid, String params, String agentJarPath) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {
        VirtualMachine vm = VirtualMachine.attach(pid);
        vm.loadAgent(agentJarPath, params);
    }

    /**
     * 加载配置文件，返回配置对象
     * @param propertyFilePath
     * @return
     */
    public static Properties loadProperties(String propertyFilePath) throws IOException {
        File file = new File(propertyFilePath);
        if (!file.exists()) {
            System.out.println("error propertyFile " + propertyFilePath + " not exist");
            exit(-1);
        }

        FileInputStream in = new FileInputStream(new File(propertyFilePath));
        InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
        Properties properties = new Properties();
        properties.load(reader);
        return properties;
    }
}

